<script setup lang="ts">
import { useDark, useFullscreen, useLocalStorage } from "@vueuse/core";
import { ElMessage } from "element-plus";
import { Particle } from "jparticles";
import { assign, throttle } from "lodash-es";
import moment from "moment";
import { io } from "socket.io-client";
import {
  computed,
  onMounted,
  onUnmounted,
  reactive,
  ref,
  shallowRef,
  watch,
} from "vue";
import { asyncgettuyaorganizesys } from "../api";
import AIChatDialog from "../components/AIChat/AIChatDialog.vue"; // 新增：导入 AI 聊天对话框组件
import FetchApi, { logdata } from "../logs/api";
import Studycodemodel from "../mysql_interface/studycodemodel"; // 新增：导入 Studycodemodel 类型
import TuyaiotModel from "../mysql_interface/tuyaiotmodel";
import { dealy } from "../util/time";
import Box from "./box.vue";
import Masonry from "./components/masonry.vue";
import {
  DeviceServiceDetailResult,
  DeviceStatusServiceStatusListResult,
  DeviceStatusServiceStatusParam,
  Icategory,
  Ituyalist,
  TuyaGetListParam,
} from "./interface";
import { bizCode, statedata } from "./statedata";
const socket = io("wss://build.hterobot.com/tuyaiot", {
  forceNew: true,
  transports: ["websocket"],
});

const isDark = useDark();
const list = ref<DeviceServiceDetailResult[]>([]);

const liststate = ref<DeviceStatusServiceStatusListResult[]>([]);

const data = ref<TuyaiotModel.ITorganize>();

const dialogFormVisible = ref(false);
const formLabelWidth = ref(80);
const form = useLocalStorage("iot-form", {
  phone: "",
  password: "",
  setZoom: false,
});

const home_id = computed(() => {
  return data.value?.home_id;
});

const showAIChat = computed(() => {
  console.log("showAIChat:", data.value);
  return data.value && data.value.name === "SSF-IOT";
});

// 新增：为 AI Chat Dialog 准备 user prop
const currentUserForAIChat = computed<Studycodemodel.Iuser | undefined>(() => {
  if (data.value) {
    // 注意：TuyaiotModel.ITorganize 和 Studycodemodel.Iuser 结构不同
    // 这里做一个简单的映射，teamid 暂时设为 null 或根据实际情况调整
    return {
      ID: data.value.ID,
      name: data.value.name, // 通常是手机号或账号名
      // isAdmin等其他字段根据需要填充或确保它们在Iuser中是可选的
    } as Studycodemodel.Iuser;
  }
  return undefined;
});

// 新增：为 AI Chat Dialog 准备 contextDataString prop
const chatContextStringForTuya = computed(() => {
  const pageName = "物联网监控平台";
  const deviceCount = list.value.length;

  // 构建设备详细信息列表，包含名称、ID和在线状态
  const deviceDetails = list.value
    .map((device) => {
      const deviceState = liststate.value.find(
        (state) => state.id === device.id
      );
      const isOnline = deviceState?.online || false;
      return `设备名称:${device.name},设备ID:${device.id},在线状态:${
        isOnline ? "在线" : "离线"
      }`;
    })
    .join("; ");

  return `当前所在页面:${pageName},home_id:${home_id.value},设备总数:${deviceCount},设备详细信息:${deviceDetails}`;
});

// 新增：为 AI Chat Dialog 准备 contextDataString 函数
function getChatContextStringForTuya() {
  const pageName = "物联网监控平台";
  const deviceCount = list.value.length;
  // console.log("getChatContextStringForTuya:", list.value, liststate.value)
  // 构建设备详细信息列表，包含名称、ID和在线状态
  const deviceDetails = list.value
    .map((device) => {
      // const deviceState = liststate.value.find(state => state.id === device.id);
      // 在线状态:${isOnline ? '在线' : '离线'}
      // const status = (device?.status || []); status:${status},
      return `设备名称:${device.name},设备ID:${device.id},online:${device?.online} `;
    })
    .join("; ");

  return `当前所在页面:${pageName},home_id:${home_id.value},设备总数:${deviceCount},设备详细信息:${deviceDetails}`;
}

const timer = ref(0);

const _tuyastateJson = shallowRef<Icategory[]>([]);
const tuyastateJson = computed<Icategory[]>(() => {
  return _tuyastateJson.value.filter((c) => c.show);
});
const newtime = ref(moment().format("HH:mm"));
const tuyalist = shallowRef<Ituyalist[]>([]);

const scrollMaxHeight = ref("100vh");
// zoom
const ratio = ref(1);
function setRatio(e: boolean) {
  const screen: any = window.screen;
  const ua = navigator.userAgent.toLowerCase();
  if (window.devicePixelRatio !== undefined) {
    ratio.value = window.devicePixelRatio;
  } else if (~ua.indexOf("msie")) {
    if (screen.deviceXDPI && screen.logicalXDPI) {
      ratio.value = screen.deviceXDPI / screen.logicalXDPI;
    }
  } else if (
    window.outerWidth !== undefined &&
    window.innerWidth !== undefined
  ) {
    ratio.value = window.outerWidth / window.innerWidth;
  }
  if (ratio.value) {
    ratio.value = Number((1 / ratio.value).toFixed(2));
  }
  let tmp = 1;
  if (e) {
    tmp = ratio.value;
  }
  (document.body.style as any).zoom = tmp;
  scrollMaxHeight.value = 100 / tmp + "vh"; // 设置滚动条区域的高度
}

watch(
  () => form.value.setZoom,
  (e) => {
    setRatio(e); // 获取最新ratio
  },
  { immediate: true }
);

const settingVisible = ref(false);
// 全屏
const el = ref(null);
const fullScreenSwitch = ref(false);
const { isFullscreen, enter, exit, toggle } = useFullscreen(el);
function fullscreen() {
  if (isFullscreen.value) {
    exit();
  } else {
    toggle();
  }
}
watch(fullScreenSwitch, (e) => {
  fullscreen();
});

onMounted(async () => {
  jp();
  const data = await fetch(
    "https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/json/tuyastatev2.json"
  );
  const value: { category: Icategory[]; list: Ituyalist[] } = await data.json();
  _tuyastateJson.value = value.category;
  tuyalist.value = value["list"];
  if (form.value.password && form.value.phone) {
    submit();
  } else {
    dialogFormVisible.value = true;
  }

  timer.value = window.setInterval(() => {
    getlogcount();
    getiotstatecount();
    newtime.value = moment().format("HH:mm");
  }, 156000);

  //
  setRatio(form.value.setZoom);
});

const getlist = throttle(_getlist, 200);

async function submit() {
  if (!form.value.password) {
    ElMessage.error("请输入密码");
    return;
  }
  if (!form.value.phone) {
    ElMessage.error("请输入账号");
    return;
  }
  const n = await asyncgettuyaorganizesys({
    phone: form.value.phone,
    password: form.value.password,
  });
  if (!n.rows.length) {
    ElMessage.error("账号密码不正确");
    dialogFormVisible.value = true;
    return;
  }
  data.value = n.rows[0];
  start();
}

const JPdom = ref();
const jpdata = ref<Particle>();

function jp() {
  if (JPdom.value) {
    jpdata.value = new Particle(JPdom.value, {
      color: "rgba(255,255,255,0.3)",
      proximity: 0.05,
      range: 0.05,
      num: 0.2,
      maxR: 3.7,
      minR: 0.6,
      maxSpeed: 0.8,
      minSpeed: 0.1,
      parallaxStrength: 3,
    });
  }
}

onUnmounted(() => {
  jpdata.value?.onDestroy();
  jpdata.value = undefined;
  window.clearInterval(timer.value);
});

const devicesDisabled = ref(false);

const listeners = ref<string[]>([]);
// 设备规格属性：指令集和状态集
const specifications = ref([]);

function setdevicesDisabled(e) {
  socket.emit("devices.Disabled", {
    phone: data.value.name,
    setdate: e,
  });
}

function start() {
  getlist();
  // socket.on('message', (e) => {
  //   if (e.payload) {
  //     getlist()
  //   }
  // })
  socket.on("devices.Disabled", (e) => {
    if (e.phone === data.value.name) {
      devicesDisabled.value = !!e.data;
    }
  });

  socket.emit("devices.Disabled", {
    phone: data.value.name,
  });

  socket.on(
    "devices.specification",
    (e: { result: DeviceFunctionServiceSpecificationResult }) => {
      specifications.value.push(e);
    }
  );
  socket.on("homes.devices", (..._data) => {
    const _list = [];
    for (const data of _data) {
      if (data.success) {
        for (const z of data.result) {
          const f = _list.findIndex((c) => c.id === z.id);
          if (f === -1) {
            _list.push(z);
          }
        }
      }
    }
    list.value = _list;
    getdeviceStatusstatusList(list.value.map((e) => e.id));
    for (const v of list.value) {
      const f = listeners.value.includes(v.id);
      if (!f) {
        const specification: DeviceStatusServiceStatusParam = {
          device_id: v.id,
        };
        socket.emit("devices.specification", specification);
        socket.on(v.id, (e) => {
          console.log(e.payload.protocol);
          if (e.payload.protocol == 4) {
            getdeviceStatusstatusList([e.payload.data.devId]);
          } else {
            if (home_id.value) {
              const devicelistoption: TuyaGetListParam = {
                home_id: home_id.value,
              };
              socket.emit("homes.devices", devicelistoption);
            }
          }
        });
        listeners.value.push(v.id);
      }
    }
  });
  socket.on("deviceStatus.statusList", (e) => {
    if (Array.isArray(e.result)) {
      for (const v of e.result) {
        const n = liststate.value.findIndex((z) => z.id === v.id);
        if (n > -1) {
          liststate.value.splice(n, 1, assign({}, liststate.value[n], v));
        } else {
          liststate.value.push(v);
        }
      }
    }
  });
  socket.on(
    "deviceStatus.status",
    (e: {
      data: DeviceStatusServiceStatusParam;
      devicelistoption: {
        result: {
          code: string;
          value: string;
        }[];
      };
    }) => {
      const { devicelistoption, data } = e;
      if (devicelistoption.result) {
        const d = liststate.value.find((e) => e.id === data.device_id);
        if (d) {
          d.status = devicelistoption.result.filter((e) => e);
        }
      }
    }
  );
  socket.on("deviceFunction.commands", (e) => {
    if (e.success) {
      ElMessage.success("发送指令成功");
    } else {
      ElMessage.error(e.msg);
    }
  });
  dialogFormVisible.value = false;
}

async function _getlist() {}

function actionsallocateemit(home_id: string, id: string, isRefresh = false) {
  socket.emit("actions.allocate", {
    uid: home_id,
    device_id: id,
    isRefresh,
  });
}

function getdeviceStatusstatusList(data: string[]) {
  const devicelistoption = {
    device_ids: data.join(","),
  };
  socket.emit("deviceStatus.statusList", devicelistoption);
}

watch(
  () => home_id.value,
  (e) => {
    if (e) {
      const devicelistoption: TuyaGetListParam = {
        home_id: e,
      };
      socket.emit("homes.devices", devicelistoption);
    }
  }
);

watch(
  () => devicesDisabled.value,
  (e) => {
    setdevicesDisabled(e);
  }
);

watch(
  () => list.value,
  (e) => {
    if (e) {
      getlogcount();
      getiotstatecount();
      getiotlogdata(0, true);
      getiotstudentlogdata(0);
      getstudentlogcount();
    }
  }
);

const formInline = reactive<logdata>({
  query: "* | with_pack_meta",
  line: 10,
  offset: 0,
  projectName: "hterobot-tuya-iot",
  logstoreName: "tuya2",
  from: new Date(moment().subtract(365, "days").unix() * 1000),
  to: new Date(moment().add(1, "days").unix() * 1000),
  reverse: true,
});

const logcount = ref(0);

function getlogcount() {
  if (list.value.length) {
    FetchApi(
      assign({}, formInline, {
        query: `* | select count(*) as count where devId in ('${list.value
          .map((c) => c.id)
          .join("','")}')`,
        line: 99,
      })
    )
      .then((e) => {
        logcount.value = Number(e.data[0].count);
      })
      .catch((c) => {
        console.log(c);
      });
  }
}

const logbyday = ref<{ count: number; day: string }[]>([]);
const logbydayp4 = ref<{ count: number; day: string; type: string }[]>([]);

function getiotstatecount() {
  if (list.value.length) {
    FetchApi(
      assign({}, formInline, {
        query: `* | select count(*) as count ,devId as day where devId in ('${list.value
          .map((c) => c.id)
          .join("','")}') group by day order by day asc  limit 99`,
      })
    )
      .then((e) => {
        logbyday.value = e.data.map((e: any) => {
          const name = list.value.find((k) => k.id === e.day)?.name;
          return {
            day: name,
            count: Number(e.count),
          };
        });
      })
      .catch((c) => {
        console.log(c);
      });

    FetchApi(
      assign({}, formInline, {
        query: `* | select count(*) as count, protocol as type, date_format(date_trunc( 'day',__time__), '%m-%d') as day where devId in ('${list.value
          .map((c) => c.id)
          .join("','")}') group by day,type order by day asc limit 99`,
        from: new Date(moment().subtract(32, "days").unix() * 1000),
        to: new Date(moment().add(1, "days").unix() * 1000),
      })
    )
      .then((e) => {
        logbydayp4.value = e.data.map((e: any) => {
          return {
            day: e.day,
            count: Number(e.count),
            type: e.type == "4" ? "设备上报" : "设备管理",
          };
        });
      })
      .catch((c) => {
        console.log(c);
      });

    // FetchApi(assign({}, formInline, {
    //   query: `protocol:20 | select count(*) as count ,date_format(date_trunc( 'day',__time__), '%m-%d') as day where devId in ('${list.value.map(c => c.id).join("','")}') group by day order by day asc`
    // })).then(e => {
    //   logbydayp20.value = e.data.map((e: any) => {
    //     return {
    //       day: e.day,
    //       count: Number(e.count)
    //     }
    //   })
    // }).catch(c => {
    //   console.log(c)
    // })
  }
}

interface Ilogdata {
  devid: string;
  protocol: number;
  status0code: string;
  status0value: any;
  status0t: number;
  __time__: string;
  bizcode: string;
}

const logtabledata = ref<
  { time: string; name: string; type: string; value: string }[]
>([]);

const offset = ref(0);
const line = ref(99);

// 设备日志
function getiotlogdata(offset: number, isRefresh = false) {
  if (list.value.length) {
    FetchApi(
      assign({}, formInline, {
        query: `* | select * where devId in ('${list.value
          .map((c) => c.id)
          .join("','")}') order by __time__ desc limit ${offset},${line.value}`,
      })
    )
      .then(async (e) => {
        if (isRefresh) {
          await dealy(1 * 1000);
        }
        logtabledata.value = e.data.map((e: Ilogdata) => {
          const time = moment(Number(e["__time__"]) * 1000).format(
            "MM-DD HH:mm"
          );
          // 获取设备基础参数
          const iot = list.value.find((c) => c.id === e.devid);
          const name = iot?.name || "";
          // 设备上报的
          if (e.protocol == 4) {
            // oss上配置的json文件
            const jsonData = _tuyastateJson.value.find(
              (c) => c.name === iot?.category && c.code === e["status0code"]
            );
            let type = jsonData?.dataname;
            let value = e["status0value"];
            if (jsonData && iot) {
              // 获取设备基础参数
              const specofic = specifications.value.find((c) => c.id == iot.id);
              const devStatusCfg = specofic?.result?.status.find(
                (z) => z.code == jsonData.code
              );
              // console.log("getiotlogdata", e)
              // console.log("getiotlogdata jsonData", jsonData,)
              // console.log("getiotlogdata specifications", specifications.value,)
              // console.log("getiotlogdata specofic", specofic)
              // console.log("getiotlogdata devStatusCfg", devStatusCfg)
              // console.log("getiotlogdata iot", iot)
              // 数据转换
              value = statedata(value, jsonData, devStatusCfg, iot);
            }
            return {
              time,
              name,
              type,
              value,
            };
          } else if (e.protocol == 20) {
            let type = "状态";
            let value = bizCode[e.bizcode];
            return {
              time,
              name,
              type,
              value,
            };
          } else {
            return {
              time,
              name,
              type: "",
              value: "",
            };
          }
        });
      })
      .catch((c) => {
        console.error(c);
      });
  }
}

type Istudentlogtype =
  | "homes.devices"
  | "deviceStatus.statusList"
  | "deviceStatus.status"
  | "deviceFunction.commands"
  | "devices.specification";

interface Istudentlogdata {
  device_id: string;
  name: string;
  type: Istudentlogtype;
  data: string;
  ip: string;
  __time__: string;
}
const studentlogcount = ref(0);
const studentoffset = ref(0);
const studentlogtabledata = ref<
  { time: string; name: string; type: string; value: string }[]
>([]);

const Istudenttype = {
  "homes.devices": "设备列表",
  "deviceStatus.statusList": "设备状态列表",
  "deviceStatus.status": "设备状态",
  "deviceFunction.commands": "设置命令",
  "devices.specification": "设备规格",
  "devices.logs": "获取日志",
};

function getiotstudentlogdata(offset: number) {
  if (list.value.length) {
    FetchApi(
      assign({}, formInline, {
        query: `* | select * where device_id in ('${list.value
          .map((c) => c.id)
          .join("','")}') or name = '${
          data.value?.name
        }' order by __time__ desc limit ${offset},${line.value}`,
        logstoreName: "tuya-student",
      })
    )
      .then((e) => {
        studentlogtabledata.value = e.data.map((e: Istudentlogdata) => {
          const time = moment(Number(e["__time__"]) * 1000).format(
            "MM-DD HH:mm"
          );
          const iot = list.value.find((c) => c.id === e.device_id);
          const name = iot?.name || "请求列表";
          return {
            time,
            name,
            type: Istudenttype[e.type],
            value: e.ip,
          };
        });
      })
      .catch((c) => {
        console.log(c);
      });
  }
}

function getstudentlogcount() {
  if (list.value.length) {
    FetchApi(
      assign({}, formInline, {
        query: `* | select count(*) as count where device_id in ('${list.value
          .map((c) => c.id)
          .join("','")}') or name = '${data.value?.name}'`,
        line: 99,
        logstoreName: "tuya-student",
      })
    )
      .then((e) => {
        studentlogcount.value = Number(e.data[0].count);
      })
      .catch((c) => {
        console.log(c);
      });
  }
}

watch(
  () => offset.value,
  (e) => {
    getiotlogdata(e);
  }
);

watch(
  () => studentoffset.value,
  (e) => {
    getiotstudentlogdata(e);
  }
);

const devs = computed(() => {
  if (data.value?.v2set) {
    const value: DeviceServiceDetailResult = list.value[0];
    const dev: {
      type: string;
      data: TuyaiotModel.ITorganizeSet;
      value: DeviceServiceDetailResult;
    }[] = [];

    if (data.value.v2set.overview.show) {
      dev.push({
        type: "overview",
        data: data.value.v2set.overview,
        value,
      });
    }
    if (data.value.v2set.percentage.show) {
      dev.push({
        type: "percentage",
        data: data.value.v2set.percentage,
        value,
      });
    }
    if (data.value.v2set.log.show) {
      dev.push({
        type: "log",
        data: data.value.v2set.log,
        value,
      });
    }
    if (data.value.v2set.table.show) {
      dev.push({
        type: "table",
        data: data.value.v2set.table,
        value,
      });
    }
    data.value.v2set.char.forEach((e) => {
      const value = list.value.find((c) => c.id === e.name);
      if (value && e.show) {
        dev.push({
          type: "char",
          data: e,
          value,
        });
      }
    });
    data.value.v2set.list.forEach((e) => {
      const value = list.value.find((c) => c.id === e.name);
      if (value && e.show) {
        dev.push({
          type: "list",
          data: e,
          value,
        });
      }
    });
    data.value.v2set.video.forEach((e) => {
      const value = list.value.find((c) => c.id === e.name);
      if (value && e.show) {
        dev.push({
          type: "video",
          data: e,
          value,
        });
      }
    });
    return dev.sort((a, b) => {
      return a.data.index - b.data.index;
    });
  } else {
    return [];
  }
});

const leftdev = computed(() => {
  return devs.value.filter((c) => c.data.Container === "left");
});

const centerdev = computed(() => {
  console.log(
    "centerdev:",
    devs.value.filter(
      (c) =>
        (!c.data.Container || c.data.Container === "center") && c.type == "char"
    )
  );
  return devs.value.filter(
    (c) => !c.data.Container || c.data.Container === "center"
  );
});

const bottomdev = computed(() => {
  return devs.value
    .filter((c) => c.data.Container === "bottom")
    .map((c) => {
      return assign(c, {
        data: {
          col: 24,
        },
      });
    });
});

const rightdev = computed(() => {
  return devs.value.filter((c) => c.data.Container === "right");
});

watch(
  () => isDark.value,
  (e) => {
    jpdata.value?.onDestroy();
    jpdata.value = undefined;
    if (e) {
      jpdata.value = new Particle(JPdom.value, {
        color: "rgba(255,255,255,0.3)",
        proximity: 0.05,
        range: 0.05,
        num: 0.2,
        maxR: 3.7,
        minR: 0.6,
        maxSpeed: 0.8,
        minSpeed: 0.1,
        parallaxStrength: 3,
      });
    } else {
      jpdata.value = new Particle(JPdom.value, {
        color: "rgba(0,0,0,0.3)",
        proximity: 0.05,
        range: 0.05,
        num: 0.2,
        maxR: 3.7,
        minR: 0.6,
        maxSpeed: 0.8,
        minSpeed: 0.1,
        parallaxStrength: 3,
      });
    }
  }
);

function reload() {
  location.reload();
}

function logout() {
  form.value.password = "";
  form.value.phone = "";
  reload();
}

function currentchange(r: number) {
  offset.value = (r - 1) * line.value;
}

function studentcurrentchange(r: number) {
  studentoffset.value = (r - 1) * line.value;
}
</script>

<template>
  <el-config-provider>
    <el-scrollbar :height="scrollMaxHeight">
      <div class="JPdom" ref="JPdom"></div>
      <el-container class="main-container">
        <el-header class="header filwrap" height="124px">
          <div class="el-header-left">
            <img
              v-if="data?.v2set?.logo"
              alt=""
              :src="data?.v2set?.logo"
              height="80px"
            />
          </div>
          <div class="el-header-center">
            {{ data?.v2set?.title || "智能设备监控平台" }}
          </div>
          <div class="el-header-right">
            <el-button class="button" @click="logout">退出</el-button>
            <el-button class="button" @click="reload">刷新</el-button>
            <el-button class="button" @click="settingVisible = true"
              >设置</el-button
            >
            <el-dialog v-model="settingVisible" title="设置" width="400" center>
              <template #header>
                <span class="icon-text el-dialog__header-title">
                  <el-icon class="text-primary">
                    <Guide />
                  </el-icon>
                  设置
                </span>
              </template>
              <el-form>
                <el-form-item label="全屏" label-width="100px">
                  <el-switch v-model="fullScreenSwitch" />
                  <!-- <el-button class="" @click="fullScreenSwitch =!fullScreenSwitch">{{ isFullscreen ? "退出全屏" : "全屏" }}</el-button> -->
                </el-form-item>
                <el-form-item label="缩放" label-width="100px">
                  <el-switch v-model="form.setZoom" />
                </el-form-item>
                <el-form-item label="设备禁用" label-width="100px">
                  <el-switch v-model="devicesDisabled" />
                </el-form-item>
                <el-form-item label="版本" label-width="100px">
                  v1.2.0
                </el-form-item>
              </el-form>
            </el-dialog>
          </div>
        </el-header>
        <el-container>
          <el-aside
            class="aside"
            v-if="data?.v2set?.left"
            :width="data.v2set.left + 'px'"
          >
            <el-row :gutter="8">
              <Box
                v-for="(v, k) in leftdev"
                :v="v"
                :list="list"
                :tuyastateJson="tuyastateJson"
                :tuyalist="tuyalist"
                :socket="socket"
                :home_id="home_id"
                :liststate="liststate"
                :logcount="logcount"
                :logbyday="logbyday"
                :logbydayp4="logbydayp4"
                :logtabledata="logtabledata"
                :offset="offset"
                :line="line"
                :studentlogcount="studentlogcount"
                :studentlogtabledata="studentlogtabledata"
                :studentoffset="studentoffset"
                :studentline="line"
                @currentchange="currentchange"
                @studentcurrentchange="studentcurrentchange"
                :newtime="newtime"
                :actionsallocateemit="actionsallocateemit"
                :specifications="specifications"
              ></Box>
            </el-row>
          </el-aside>
          <el-main class="el-main">
            <el-row :gutter="8">
              <Box
                v-for="(v, k) in centerdev"
                :v="v"
                :list="list"
                :tuyastateJson="tuyastateJson"
                :tuyalist="tuyalist"
                :socket="socket"
                :home_id="home_id"
                :liststate="liststate"
                :logcount="logcount"
                :logbyday="logbyday"
                :logbydayp4="logbydayp4"
                :logtabledata="logtabledata"
                :offset="offset"
                :line="line"
                :studentlogcount="studentlogcount"
                :studentlogtabledata="studentlogtabledata"
                :studentoffset="studentoffset"
                :studentline="line"
                @currentchange="currentchange"
                @studentcurrentchange="studentcurrentchange"
                :newtime="newtime"
                :actionsallocateemit="actionsallocateemit"
                :specifications="specifications"
              ></Box>
            </el-row>
            <Masonry
              v-if="data?.v2set?.bottom"
              :columns="data.v2set.bottom"
              :column-gap="8"
            >
              <Box
                v-for="(v, k) in bottomdev"
                :v="v"
                :list="list"
                :tuyastateJson="tuyastateJson"
                :tuyalist="tuyalist"
                :socket="socket"
                :home_id="home_id"
                :liststate="liststate"
                :logcount="logcount"
                :logbyday="logbyday"
                :logbydayp4="logbydayp4"
                :logtabledata="logtabledata"
                :offset="offset"
                :line="line"
                :studentlogcount="studentlogcount"
                :studentlogtabledata="studentlogtabledata"
                :studentoffset="studentoffset"
                :studentline="line"
                @currentchange="currentchange"
                @studentcurrentchange="studentcurrentchange"
                :newtime="newtime"
                :actionsallocateemit="actionsallocateemit"
                :specifications="specifications"
              ></Box>
            </Masonry>
          </el-main>
          <el-aside
            class="aside"
            v-if="data?.v2set?.right"
            :width="data.v2set.right + 'px'"
          >
            <el-row :gutter="8">
              <Box
                v-for="(v, k) in rightdev"
                :v="v"
                :list="list"
                :tuyastateJson="tuyastateJson"
                :tuyalist="tuyalist"
                :socket="socket"
                :home_id="home_id"
                :liststate="liststate"
                :logcount="logcount"
                :logbyday="logbyday"
                :logbydayp4="logbydayp4"
                :logtabledata="logtabledata"
                :offset="offset"
                :line="line"
                :studentlogcount="studentlogcount"
                :studentlogtabledata="studentlogtabledata"
                :studentoffset="studentoffset"
                :studentline="line"
                @currentchange="currentchange"
                @studentcurrentchange="studentcurrentchange"
                :newtime="newtime"
                :actionsallocateemit="actionsallocateemit"
                :specifications="specifications"
              ></Box>
            </el-row>
          </el-aside>
        </el-container>
      </el-container>
    </el-scrollbar>
    <el-dialog v-model="dialogFormVisible" :width="500" title="登录" center>
      <template #header>
        <span class="icon-text el-dialog__header-title">
          <el-icon class="text-primary">
            <User />
          </el-icon>
          登录
        </span>
      </template>
      <el-form :model="form">
        <el-form-item label="账号" :label-width="formLabelWidth">
          <el-input
            v-model="form.phone"
            placeholder="手机号/账号"
            autocomplete="off"
          />
        </el-form-item>
        <el-form-item label="密码" :label-width="formLabelWidth">
          <el-input
            v-model="form.password"
            type="password"
            autocomplete="off"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button class="button" @click="dialogFormVisible = false"
            >取消</el-button
          >
          <el-button class="button" type="primary" @click="submit">
            登录
          </el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 新增：AI 聊天对话框组件 -->
    <AIChatDialog
      v-if="showAIChat"
      :user="currentUserForAIChat"
      :contextDataString="getChatContextStringForTuya()"
      :enableInNoStoreContext="true"
    />
  </el-config-provider>
</template>

<style scoped>
.el-main {
  --el-main-padding: 0px 8px;
}

.aside {
  overflow: hidden;
  padding-left: 5px;
  padding-right: 5px;
}

.main-container {
  z-index: 2;
  position: relative;
  height: 100vh;
  color: #fff;
  --el-color-success: #5fd56b;
  font-family: Microsoft YaHei, Arial;
}

.JPdom {
  position: fixed;
  height: 100%;
  width: 100%;
  background-color: rgb(42, 44, 59);
}

.el-header-center {
  font-size: 36px;
  font-weight: 600;
  /* position: absolute;
  width: 100%;
  text-align: center;
  z-index :-1; */
}

.button {
  color: #fff;
  background-color: transparent;
}

.button:hover {
  color: #000;
  background-color: #fff;
}
</style>

<style>
* {
  padding: 0;
  margin: 0;
}

.flex-grow {
  flex-grow: 1;
}

.box {
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  box-shadow: var(--el-box-shadow-lighter);
}

/* 弹出层、按钮 */
.el-dialog {
  background-color: rgb(42, 44, 59, 0.96);
  border-radius: 10px;
}

.el-form-item__label,
.el-dialog__title,
.el-dialog__header-title,
.el-form-item__content {
  color: #fff !important;
}

.el-dialog .el-switch__core .el-switch__action {
  background: linear-gradient(#f3faf4, #fff);
}

#app {
  position: relative;
}

.el-pagination {
  --el-pagination-button-disabled-bg-color: rgba(0, 0, 0, 0);
}

.el-card__header {
  --el-card-border-color: rgba(0, 0, 0, 0);
  /* font-family: FZZongYi-M05S; */
  font-weight: 600;
}

.text-center {
  text-align: center !important;
}

.bg-line {
  /* background-color: #e9e9eb; */
  background-color: rgba(32, 34, 46, 0.7);
  border-radius: 4px;
}

/* html.dark .bg-line {
  background-color: rgb(32, 34, 46);
} */

.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

.filwrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
}

.dian {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  display: inline-block;
}

.bg-success1 {
  background: linear-gradient(#f3faf4, #69d775);
}

.bg-info1 {
  background-color: var(--el-color-info);
}

.el-card__header {
  padding: 16px 12px 8px 12px;
}

.el-statistic {
  --el-statistic-content-color: #fff;
}

.el-table {
  --el-table-bg-color: rgba(0, 0, 0, 0);
  --el-table-text-color: #fff;
  --el-table-header-text-color: #fff;
  --el-table-header-bg-color: var(--el-table-bg-color);
  --el-table-tr-bg-color: var(--el-table-bg-color);
  --el-table-row-hover-bg-color: var(--el-table-bg-color);
  --el-table-border: none;
  --el-table-border-color: var(--el-table-bg-color);
}

.sciencecenter .el-table .cell {
  /* height: 21px; */
  word-break: keep-all;
  /* line-height: 21px; */
}

.sciencecenter .el-table__header-wrapper {
  font-size: 16px !important;
  font-family: "FZZongYi-M05S";
  height: 30px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
  padding: 0px 0px 12px;
}

.sciencecenter .el-table__header-wrapper .cell {
  height: 16px;
  line-height: 16px !important;
  font-weight: 400;
  margin-top: -6px;
}

.sciencecenter .el-table--small .el-table__cell {
  padding: 6px 0 !important;
}

.sciencecenter .el-table--small .cell {
  padding: 0 !important;
}

.sciencecenter .color0 a {
  --el-table-text-color: #00c2ff;
  color: #00c2ff;
  text-decoration: none;
}

.sciencecenter .color0 a:hover {
  font-weight: 700;
}

.sciencecenter .color0 .el-table__header-wrapper .color0 a {
  --el-table-text-color: transparent;
  color: transparent;
}

.sciencecenter .el-table__header-wrapper .color0 .cell a {
  background: linear-gradient(315deg, #0670f8 0%, #34c7fc 100%);
  background-clip: text;
  -webkit-background-clip: text;
}

.sciencecenter .color1 {
  --el-table-text-color: transparent;
  color: transparent;
  font-weight: 700;
}

.sciencecenter .color1 .cell {
  background: linear-gradient(180deg, #50fe83 0%, #1cdd5e 100%);
  background-clip: text;
  -webkit-background-clip: text;
}

.sciencecenter .cell span {
  font-family: Bebas;
}

.sciencecenter .color2 {
  --el-table-text-color: transparent;
  color: transparent;
}

.sciencecenter .color0 {
  color: #409eff;
}

.sciencecenter .color2 .cell {
  background: linear-gradient(180deg, #fcf100 0%, #f5a300 100%);
  background-clip: text;
  -webkit-background-clip: text;
}

.sciencecenter .el-progress__text {
  --el-text-color-regular: #fff;
  font-size: 12px !important;
}
</style>
